import {
  IPostprocessData,
  IResultNew,
  isIPostprocessData,
  ModelEventType,
  NMToolBaseCommand,
  NMToolCmdDialogParams,
  VisualType,
} from '@app-nextmesh/types';
import { i18n } from '@app-nextmesh/common/utils';
import { CommandDialog, IData } from '@amcax/base';
import styled from 'styled-components';
import { useProjectStore } from '@app-nextmesh/store/project';
import React, { useEffect, useState } from 'react';
import { ISelectOption } from '@app-nextmesh/components/types';
import { Col, Row, Select, Button, Table, TableProps } from 'antd';
import { documentV2 } from '@app-nextmesh/domain';
import { clearModel } from '@app-nextmesh/utils/canvas';
import { events, updateModelsVisible } from '@app-nextmesh/utils';
import {
  clearField,
  renderFields,
  resetMeshAndWireframe,
} from '@app-nextmesh/utils/renderModel';
import { documentManager } from '@app-nextmesh/manager';

const WrapperStyle = styled.div`
  row-gap: 8px;
  width: 350px;
  padding: 0 30px 0 20px;
  padding-bottom: 8px;
  display: flex;
  flex-direction: column;

  .form-dialog_footer {
    width: 100%;
    padding: 8px 0 12px !important;
  }
`;

interface SelectedType {
  model?: string | number;
  step?: string | number;
  fieldName?: string | number;
  resolved?: string | number;
  layer?: string | number;
  variableName?: string | number;
  filter?: string | number;
  greater?: string | number;
  less?: string | number;
  frame?: string | number;
}

interface DataType {
  key: React.Key;
  frame: string;
}

interface TaskType {
  uuid: string;
  name: string;
}

function CmdCloudPictureDialog({ title, onClose }: NMToolCmdDialogParams) {
  const projectInfo = useProjectStore((state) => state.projectInfo);
  const [resultsData, setResultsData] = useState([]); // 获取任务uuid
  const [currentTask, setCurrentTask] = useState<TaskType>(null); // 获取当前任务信息
  const [loading, setLoading] = useState(false); // 应用按钮是否在加载中
  const [resultSelected, setResultSelected] = useState<SelectedType>(null); // 记录选的数据源，model, step,field,format,layer,variable等信息
  const [stepData, setStepData] = useState<ISelectOption[]>([]); // 获取步数数据
  const [fieldData, setFieldData] = useState<ISelectOption[]>([]); // 获取场数数据
  const [resultsAllData, setResultsAllData] = useState<IResultNew>(null); // 获取某个任务的相关数据
  const [applyShow, setApplyShow] = useState<boolean>(true); // 是否可点击应用
  const [layerShow, setLayerShow] = useState<boolean>(false); // 是否展示layer
  const [variableData, setVariableData] = useState([]); // 记录可变因素数据
  const [valueFilter, setValueFilter] = useState([]); // 记录筛选大小值
  const [framesData, setFramesData] = useState([]); // 记录帧数据
  const [columnsData, setColumnsData] = useState([]); // 获取表格动态头部
  const [fieldType, setFieldType] = useState(null); // 记录field类型数据

  useEffect(() => {
    // 隐藏场景中的全部几何和网格,方便看结果的网格
    updateModelsVisible('hide');
    const resultsList = [];
    if (projectInfo.results.length !== 0) {
      projectInfo.results.forEach((item: any) =>
        resultsList.push({
          label: item.name,
          value: item.uuid,
          taskId: item.taskId,
        }),
      );
      events.emit(
        ModelEventType.Loading,
        VisualType.ResultMesh,
        projectInfo.results[0].uuid,
      );
      initFormData(projectInfo.results[0].uuid);
      setValueFilter([
        {
          lable: 'None',
          value: 'None',
        },
        {
          lable: '<=',
          value: '<=',
        },
        {
          lable: '>=',
          value: '>=',
        },
        {
          lable: 'Range',
          value: 'Range',
        },
      ]);
      setResultsData(resultsList);
    }
    const meshesId = documentManager.getMeshesId();
    return () => {
      clearField();
      resetMeshAndWireframe(meshesId);
    };
  }, [projectInfo]);

  const initFormData = (value) => {
    documentV2.resultInfo(value as string).then((req) => {
      setResultsAllData(req);
      if (req?.solve?.length !== 0) {
        const simulateData = req?.solve;
        const stepList = [];
        simulateData.forEach((item) => {
          stepList.push({
            label: item.step,
            value: item.step,
          });
        });
        const fieldList = [];
        const variableList = [];
        let framesList = [];
        simulateData.forEach((item: any) => {
          if (item.step === 0) {
            item.field.forEach((f) => {
              fieldList.push({
                label: f.name,
                value: f.name,
                type: f.type,
                variable: f.Variable,
              });
            });
            if (item.field.length !== 0) {
              item.field[0].Variable.forEach((item) => {
                variableList.push({
                  label: item,
                  value: item,
                });
              });
            }
            framesList = item.frames.map((item, index) => {
              return { ...item, key: index };
            });
          }
        });
        initTable(framesList);
        setFramesData(framesList);
        setVariableData(variableList);
        setFieldData(fieldList);
        setCurrentTask({
          name: projectInfo.results[0].name,
          uuid: projectInfo.results[0].uuid,
        });
        setResultSelected({
          model: value,
          step: stepList[0].value,
          fieldName: fieldList[0].value,
          frame: framesList[0].frame,
        });
        setFieldType(fieldList[0].type);
        setStepData(stepList);
        if (fieldList[0].type === 'scalar') {
          setApplyShow(false);
        }
      }
    });
  };

  const initTable = (framesList) => {
    // 提取所有唯一的字段名作为表头
    const allKeys = framesList.reduce((acc, item) => {
      return [...acc, ...Object.keys(item)];
    }, []);
    // 去重
    const uniqueKeys = [...new Set(allKeys)].filter(
      (item) => item !== 'field_data' && item !== 'key' && item !== 'lsdvmn',
    );
    // 根据字段名生成表头
    const columns = uniqueKeys.map((key: any, index) => ({
      title: key.toUpperCase(), // 使用字段名作为表头
      dataIndex: key, // 数据中的键
      key: key, // 唯一标识
      width: 30,
    }));
    setColumnsData(columns);
  };

  // 处理不同下拉选择业务数据
  const handleResultSelectChange = (value: string | number, type: string) => {
    let params = resultSelected;
    setApplyShow(true);
    switch (type) {
      case 'model':
        params = {
          model: value,
          step: undefined,
          fieldName: undefined,
          variableName: undefined,
        };
        initFormData(value);
        events.emit(ModelEventType.Loading, VisualType.ResultMesh, value);
        setResultSelected({
          ...params,
        });
        resultsData.forEach((item) => {
          if (item.value === value) {
            setCurrentTask({
              name: item.label,
              uuid: item.value,
            });
          }
        });
        if (resultsAllData?.solve?.length !== 0) {
          const simulateData = resultsAllData?.solve;
          const stepList = [];
          const fieldList = [];
          const framesList = [];
          simulateData.forEach((item) => {
            stepList.push({
              label: item.step,
              value: item.step,
            });
            item.frames.map((item, index) => {
              framesList.push({ ...item, key: index });
            });
            item.field.forEach((f) => {
              fieldList.push({
                label: f.name,
                value: f.name,
                type: f.type,
                variable: f.Variable,
              });
            });
          });
          setFieldData(fieldList);
          setStepData(stepList);
          initTable(framesList);
        }
        break;
      case 'step':
        params = {
          ...params,
          step: value,
        };
        setResultSelected({
          ...params,
        });
        const fieldList = [];
        resultsAllData.solve.forEach((item) => {
          if (item.step === params.step) {
            item.field.forEach((f) => {
              fieldList.push({
                label: f.name,
                value: f.name,
                type: f.type,
                variable: f.Variable,
              });
            });
          }
        });
        setFieldData(fieldList);
        break;
      case 'field':
        params = {
          ...params,
          fieldName: value,
          layer: undefined,
          filter: undefined,
          greater: undefined,
          less: undefined,
          variableName: undefined,
        };
        setLayerShow(false);
        const variableList = [];
        fieldData.map((item) => {
          if (item.label === value && item.type === 'tensor') {
            setLayerShow(true);
          }
          if (item.label === value) {
            setFieldType(item.type);
            item.variable.forEach((v) => {
              variableList.push({
                label: v,
                value: v,
              });
            });
          }
        });
        setVariableData(variableList);
        setResultSelected({
          ...params,
        });
        break;
      case 'variable':
        params = {
          ...params,
          variableName: value,
          layer: undefined,
          filter: undefined,
          greater: null,
          less: null,
        };
        setResultSelected({
          ...params,
        });
        break;
      case 'layer':
        params = {
          ...params,
          layer: value,
        };
        setResultSelected({
          ...params,
        });
        break;
      case 'filter':
        params = {
          ...params,
          filter: value,
          greater: null,
          less: null,
        };
        setResultSelected({
          ...params,
        });
        break;
      case 'greater':
        params = {
          ...params,
          greater: value,
        };
        setResultSelected({
          ...params,
        });
        break;
      case 'less':
        params = {
          ...params,
          less: value,
        };
        setResultSelected({
          ...params,
        });
        break;
    }
    if (fieldType !== 'scalar') {
      if (
        params.fieldName !== undefined &&
        params.step !== undefined &&
        params.variableName !== undefined &&
        params.frame !== undefined
      ) {
        setApplyShow(false);
      }
    } else {
      if (
        params.fieldName !== undefined &&
        params.step !== undefined &&
        params.frame !== undefined
      ) {
        setApplyShow(false);
      }
    }
  };

  const rowSelection: TableProps<DataType>['rowSelection'] = {
    type: 'radio', // 设置为 'radio' 实现单选
    selectedRowKeys: [resultSelected?.frame],
    onChange: (selectedRowKeys: React.Key[], selectedRows: DataType[]) => {
      const newParams = {
        ...resultSelected,
        frame: Number(selectedRows[0].frame),
      };

      if (fieldType !== 'scalar') {
        if (
          newParams.fieldName !== undefined &&
          newParams.step !== undefined &&
          newParams.variableName !== undefined &&
          newParams.frame !== undefined
        ) {
          setApplyShow(false);
        }
      } else {
        if (
          newParams.fieldName !== undefined &&
          newParams.step !== undefined &&
          newParams.frame !== undefined
        ) {
          setApplyShow(false);
        }
      }
      setResultSelected(newParams);
    },
  };

  // 获取后端云图数据渲染
  const changeField = async (data: TaskType, params: SelectedType) => {
    if (params?.fieldName) {
      const req: IData[] | IPostprocessData = await documentV2.resultData(
        data.uuid,
        params,
      );
      clearField();
      if (isIPostprocessData(req)) {
        events.emit(ModelEventType.SetExtra, req.extra);
        renderFields(req.fields, 'jet');
        setLoading(false);
      }
    }
  };
  return (
    <CommandDialog
      title={title}
      placement='topLeft'
      onClose={onClose}>
      <WrapperStyle>
        <Row>
          <Col span={12}>Model:</Col>
          <Col span={12}>
            <Select
              disabled={loading}
              value={resultSelected?.model}
              style={{ width: 150 }}
              onChange={(value) => handleResultSelectChange(value, 'model')}
              options={resultsData}
            />
          </Col>
        </Row>
        <Row>
          <Col span={12}>Step:</Col>
          <Col span={12}>
            <Select
              disabled={loading}
              style={{ width: 150 }}
              onChange={(value) => handleResultSelectChange(value, 'step')}
              value={resultSelected?.step}
              options={stepData}
            />
          </Col>
        </Row>
        <Row>
          <Col span={3}>Field:</Col>
          <Col span={13}>
            <Select
              disabled={loading}
              style={{ width: 150 }}
              onChange={(value) => handleResultSelectChange(value, 'field')}
              allowClear
              value={resultSelected?.fieldName}
              options={fieldData}
            />
          </Col>
          {fieldType !== 'scalar' && (
            <Col span={8}>
              <Select
                disabled={loading}
                style={{ width: 100 }}
                onChange={(value) =>
                  handleResultSelectChange(value, 'variable')
                }
                value={resultSelected?.variableName}
                options={variableData}
              />
            </Col>
          )}
        </Row>
        {/* <Row>
          <Col span={3}>Value:</Col>
          <Col span={9}>
            <Select
              disabled={loading}
              style={{ width: 110 }}
              onChange={(value) => handleResultSelectChange(value, 'filter')}
              allowClear
              value={resultSelected?.filter}
              options={valueFilter}
            />
          </Col>
          {resultSelected?.filter !== 'None' &&
            resultSelected?.filter !== undefined && (
              <>
                {(resultSelected?.filter === '>=' ||
                  resultSelected?.filter === 'Range') && (
                  <Col span={6}>
                    <InputNumber
                      disabled={loading}
                      style={{ width: 75 }}
                      value={resultSelected?.greater}
                      onChange={(value) =>
                        handleResultSelectChange(value, 'greater')
                      }
                    />
                  </Col>
                )}
                {(resultSelected?.filter === '<=' ||
                  resultSelected?.filter === 'Range') && (
                  <Col span={6}>
                    <InputNumber
                      disabled={loading}
                      style={{ width: 75 }}
                      value={resultSelected?.less}
                      onChange={(value) =>
                        handleResultSelectChange(value, 'less')
                      }
                    />
                  </Col>
                )}
              </>
            )}
        </Row>*/}
        {/*{layerShow && (
          <Row>
            <Col span={12}>Layer:</Col>
            <Col span={12}>
              <Select
                disabled={loading}
                style={{ width: 150 }}
                onChange={(value) => handleResultSelectChange(value, 'layer')}
                allowClear
                value={resultSelected?.layer}
                options={[
                  {
                    label: 't',
                    value: 't',
                  },
                  {
                    label: 'b',
                    value: 'b',
                  },
                ]}
              />
            </Col>
          </Row>
        )}*/}
        <div style={{ width: '100%', margin: '0 auto' }}>
          <Row>
            <Col span={12}>Frames:</Col>
          </Row>
          <Table
            rowSelection={rowSelection}
            dataSource={framesData}
            pagination={false}
            columns={columnsData}
            scroll={{ x: 'auto' }}
          />
        </div>
        <Button
          loading={loading}
          disabled={applyShow}
          style={{ width: '100px', marginLeft: '100px' }}
          onClick={async () => {
            clearModel();
            setLoading(true);
            changeField(currentTask, resultSelected);
          }}>
          Apply
        </Button>
      </WrapperStyle>
    </CommandDialog>
  );
}
// 云图
export const cmdCloudPicture: NMToolBaseCommand = {
  id: 'CmdCloudPicture',
  label: 'command.draw.cloud-picture',
  icon: 'commands/simu/cloud',
  create: (label, onClose) => (
    <CmdCloudPictureDialog
      title={i18n.t(label)}
      onClose={onClose}
    />
  ),
};
